using System;
using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;

public class PlayerMecanimWrapper : MonoBehaviour
{
	private const float IDLE_VELOCITY = 0.05f;

	private const float MAX_VELOCITY = 8f;

	private const float TRANSITION_STATE_TIME = 5f;

	private const float MAX_HEAD_ANGLE = 10f;

	private const float MAX_TORSO_ANGLE = 40f;

	public Transform torso;

	public Transform head;

	private PlayerBehavior curentBehavior;

	public bool isMob;

	public bool shopPlayer;

	[HideInInspector]
	public bool checkGround;

	[HideInInspector]
	public float mobVelocity;

	[SerializeField]
	private Animator _animator;

	private float _maxVelocity;

	private Renderer mesh;

	private float curTransitionTime;

	private bool isIdle;

	[HideInInspector]
	public bool FPSCameraEnabled;

	public Animator FPSCameraAnimator;

	public GameObject PlayerMech;

	public GameObject PlayerMechFPS;

	[HideInInspector]
	public bool DeadAnimIsPlayed;

	private bool _inWater;

	private bool _isGrounded;

	private Camera mainCamera;

	private Vector3 bodyRotation;

	private Vector3 headRotation;

	private bool neddTurn;

	[SerializeField]
	private PlayerTransformPhoton lerpScript;

	private bool isShooting;

	private bool isMoving;

	public Transform parentObjectTransform;

	public bool inParent;

	public bool forceStartAnimations;

	private bool inCar;

	public bool lert;

	public bool isMobMoving;

	public float currentVelocuty;

	private float prevVel;

	public bool isShootHold
	{
		get
		{
			return _animator.GetBool("WeaponShootHold");
		}
	}

	public bool inWater
	{
		get
		{
			return _inWater;
		}
		set
		{
			if (!_animator.GetBool("OnLadder"))
			{
				SwitchUpperLayer(!value, true);
			}
			_inWater = value;
			SetBoolAnim("InWater", value);
			if (!isMob)
			{
				if (value)
				{
					_maxVelocity = 3.2f;
				}
				else
				{
					_maxVelocity = 8f;
				}
			}
		}
	}

	public bool isGrounded
	{
		get
		{
			return _isGrounded;
		}
		set
		{
			_isGrounded = value;
			SetIsGrounded(value);
		}
	}

	public event Action<bool> eventHoldShoot;

	public event Action<bool> eventAimMode;

	private void Start()
	{
		_animator.logWarnings = false;
		inWater = false;
		isGrounded = true;
		curentBehavior = GetComponent<PlayerBehavior>();
		mainCamera = Camera.main;
		neddTurn = !isMob && !shopPlayer && torso != null && head != null;
		if (SceneManager.GetActiveScene().name != "Lobby" && lerpScript == null)
		{
			lerpScript = GetComponent<PlayerTransformPhoton>();
		}
		if (forceStartAnimations)
		{
			mobVelocity = 3f;
			StartCheck(GetComponentInChildren<SkinnedMeshRenderer>());
		}
	}

	private void LateUpdate()
	{
		if (inCar && !_animator.GetCurrentAnimatorStateInfo(0).IsName((!lert) ? "CarGetInR" : "CarGetInL") && !_animator.GetCurrentAnimatorStateInfo(0).IsName("Car"))
		{
			GetInCar(lert);
		}
		else
		{
			ResetTriggerAnim("CarGetInL");
			ResetTriggerAnim("CarGetInR");
		}
		if (!neddTurn || FPSCameraEnabled)
		{
			return;
		}
		bodyRotation = torso.localEulerAngles;
		headRotation = head.localEulerAngles;
		if (isShooting || isMoving)
		{
			float num = ((!curentBehavior.isMine) ? lerpScript.yCameraAngle : mainCamera.transform.eulerAngles.x);
			if (num > 180f)
			{
				num -= 360f;
			}
			if (num < -180f)
			{
				num += 360f;
			}
			if (num > 10f)
			{
				headRotation.y = 10f;
				bodyRotation.y = num - 10f;
				if (bodyRotation.y > 40f)
				{
					bodyRotation.y = 40f;
				}
			}
			else if (num < -10f)
			{
				headRotation.y = -10f;
				bodyRotation.y = num + 10f;
				if (bodyRotation.y < -40f)
				{
					bodyRotation.y = -40f;
				}
			}
			else
			{
				bodyRotation.y = 0f;
				headRotation.y = num;
			}
			torso.localEulerAngles = bodyRotation;
			head.localEulerAngles = headRotation;
		}
		else
		{
			bodyRotation.y = 0f;
			headRotation.y = 0f;
			torso.localEulerAngles = bodyRotation;
			head.localEulerAngles = headRotation;
		}
	}

	private void SetTriggerAnim(string trigger, bool forFPS = true)
	{
		_animator.SetTrigger(trigger);
		if (forFPS && FPSCameraEnabled)
		{
			FPSCameraAnimator.SetTrigger(trigger);
		}
	}

	private void ResetTriggerAnim(string trigger)
	{
		_animator.ResetTrigger(trigger);
		if (FPSCameraEnabled)
		{
			FPSCameraAnimator.ResetTrigger(trigger);
		}
	}

	private void SetBoolAnim(string name, bool value, bool forFPS = true)
	{
		_animator.SetBool(name, value);
		if (forFPS && FPSCameraEnabled)
		{
			FPSCameraAnimator.SetBool(name, value);
		}
	}

	private void SetFloatAnim(string name, float value, bool forFPS = true)
	{
		_animator.SetFloat(name, value);
		if (forFPS && FPSCameraEnabled)
		{
			FPSCameraAnimator.SetFloat(name, value);
		}
	}

	public void Idle(bool val)
	{
		_animator.SetBool("IsIdle", val);
		isMobMoving = !val;
	}

	public void Jump()
	{
		SetTriggerAnim("Jump");
		RefreshTransitionState();
	}

	public void Dead()
	{
		inCar = false;
		DeadAnimIsPlayed = true;
		Idle(false);
		SwitchUpperLayer(false);
		ResetTriggerAnim("Respawn");
		SetTriggerAnim("Death", false);
		SetFloatAnim("DeathType", 0f);
	}

	public void Dead(PlayerDeadAnimation dead)
	{
		inCar = false;
		DeadAnimIsPlayed = true;
		Idle(false);
		SwitchUpperLayer(false);
		SetTriggerAnim("Death", false);
		ResetTriggerAnim("Respawn");
		SetFloatAnim("DeathType", (float)dead);
	}

	public void Respawn()
	{
		inCar = false;
		HoldShoot(false);
		DeadAnimIsPlayed = false;
		SetBoolAnim("Downed", false);
		SwitchUpperLayer(false);
		SetTriggerAnim("Respawn");
		ResetTriggerAnim("Death");
		StopCoroutine(OnUpperBody());
		StartCoroutine(OnUpperBody());
		RefreshTransitionState();
	}

	public void DropDown()
	{
		inCar = false;
		SwitchUpperLayer(false);
		SetTriggerAnim("DropDown", false);
		SetBoolAnim("Downed", true, false);
		RefreshTransitionState();
	}

	public void DropDownMajor()
	{
		Debug.LogError("DropDownMajor");
		inCar = false;
		SwitchUpperLayer(false);
		SetTriggerAnim("DropDownMajor", false);
		SetBoolAnim("Downed", true, false);
		RefreshTransitionState();
	}

	public void StandUp()
	{
		inCar = false;
		SwitchUpperLayer(true);
		SetTriggerAnim("StandUp");
		SetBoolAnim("Downed", false);
		RefreshTransitionState();
	}

	public void SwitchLadder(bool value)
	{
		SetBoolAnim("OnLadder", value);
		SwitchUpperLayer(!value);
	}

	public void SwitchRoll(bool value)
	{
		SetBoolAnim("RollHeight", value && CameraModeControl.instance.mainCameraType != settings.MainCameraType.FPSCamera, false);
	}

	public void PlayDemoAnim()
	{
		SetTriggerAnim("WeaponDemo");
	}

	public void GetInCar(bool left)
	{
		inCar = true;
		lert = left;
		ResetTriggerAnim("CarGetInL");
		ResetTriggerAnim("CarGetInR");
		ResetTriggerAnim("CarGetOut");
		ResetTriggerAnim("CarGetOutR");
		ResetTriggerAnim("CarGetOutL");
		StopCoroutine(OnUpperBody());
		SwitchUpperLayer(false);
		SetTriggerAnim((!left) ? "CarGetInR" : "CarGetInL");
	}

	public void GetOutCar(bool left)
	{
		inCar = false;
		StopCoroutine(OnUpperBody());
		if (base.gameObject.activeSelf)
		{
			StartCoroutine(OnUpperBody());
		}
		ResetTriggerAnim("CarGetInL");
		ResetTriggerAnim("CarGetInR");
		ResetTriggerAnim("CarGetOut");
		ResetTriggerAnim("CarGetOutR");
		ResetTriggerAnim("CarGetOutL");
		SetTriggerAnim((!left) ? "CarGetOutL" : "CarGetOutR");
	}

	public void PrepareToSit()
	{
		SetTriggerAnim("MotoLift");
	}

	public void SetFPSMechState(bool enable)
	{
		PlayerMech.SetActive(!enable);
		PlayerMechFPS.SetActive(enable);
		FPSCameraEnabled = enable;
		_animator.SetBool("FPSEdit", enable);
	}

	public void SetIsGrounded(bool value)
	{
		SetBoolAnim("IsGrounded", value);
	}

	public void ShootRight()
	{
		if (!_animator.GetCurrentAnimatorStateInfo(0).IsName("Reload"))
		{
			_animator.SetTrigger("WeaponShootR");
		}
		RefreshTransitionState();
	}

	public void ShootRightAlt()
	{
		_animator.SetTrigger("WeaponShootRAlt");
		RefreshTransitionState();
	}

	public void ShootLeft()
	{
		_animator.SetTrigger("WeaponShootL");
		RefreshTransitionState();
	}

	public void ShootLeftAlt()
	{
		_animator.SetTrigger("WeaponShootLAlt");
		RefreshTransitionState();
	}

	public void Reload()
	{
		_animator.ResetTrigger("CancelWeaponReload");
		_animator.SetTrigger("WeaponReload");
		RefreshTransitionState();
	}

	public void CancelReload()
	{
		_animator.SetTrigger("CancelWeaponReload");
	}

	public void Empty()
	{
		_animator.SetTrigger("WeaponEmpty");
		RefreshTransitionState();
	}

	public void Holster()
	{
		_animator.SetTrigger("WeaponHolster");
	}

	public void DeactivateShootTriggers()
	{
		if (_animator != null)
		{
			_animator.ResetTrigger("WeaponShootR");
			_animator.ResetTrigger("WeaponShootRAlt");
			_animator.ResetTrigger("WeaponShootL");
			_animator.ResetTrigger("WeaponShootLAlt");
		}
	}

	public void SetWeaponPullable(bool value)
	{
		SetBoolAnim("WeaponIsPullable", value);
	}

	public void SwitchAim(bool value)
	{
		SetBoolAnim("WeaponAim", value);
		if (this.eventAimMode != null)
		{
			this.eventAimMode(value);
		}
	}

	public void SetWeaponPull(float value)
	{
		SetFloatAnim("WeaponPull", value);
	}

	public void HoldShoot(bool value)
	{
		if (_animator != null)
		{
			_animator.SetBool("WeaponShootHold", value);
		}
		if (this.eventHoldShoot != null)
		{
			this.eventHoldShoot(value);
		}
		if (!value)
		{
			DeactivateShootTriggers();
		}
		isShooting = value;
	}

	public void StartCheck(Renderer skinnedMesh)
	{
		mesh = skinnedMesh;
		StopAllCoroutines();
		SwitchUpperLayer(true);
		SetBoolAnim("IsMoving", false);
		if (base.gameObject.activeInHierarchy)
		{
			StartCoroutine(CheckAnimation());
		}
	}

	public void SwitchUpperLayer(bool value, bool force = false)
	{
		if ((!inWater || force) && _animator != null && _animator.layerCount > 1)
		{
			int num = 0;
			if (value && !inCar)
			{
				num = 1;
			}
			if (_animator.GetLayerWeight(1) != (float)num)
			{
				_animator.SetLayerWeight(1, num);
			}
		}
	}

	public void SetWeapon(RuntimeAnimatorController overrideController, float reloadTime = 1f, float timeBetweenShots = 1f, bool pullable = false)
	{
		CancelReload();
		SetAnimatorController(overrideController);
		SwitchUpperLayer(true);
		SetBoolAnim("WeaponIsPullable", pullable);
		CalculateAnimationSpeed(reloadTime, timeBetweenShots);
		Holster();
	}

	public void SetAnimatorController(RuntimeAnimatorController controller)
	{
		if (base.gameObject.activeInHierarchy)
		{
			StartCoroutine(SetRuntimeAnimatorController(controller));
		}
	}

	private IEnumerator SetRuntimeAnimatorController(RuntimeAnimatorController overrideController)
	{
		while (true)
		{
			bool isActive = true;
			Transform tr = base.transform;
			while (tr != tr.root)
			{
				if (!tr.gameObject.activeSelf)
				{
					isActive = false;
					break;
				}
				tr = tr.parent;
			}
			if (isActive)
			{
				break;
			}
			yield return null;
		}
		_animator.runtimeAnimatorController = overrideController;
	}

	private IEnumerator CheckAnimation()
	{
		if (_animator == null)
		{
			yield break;
		}
		float prevX = 0f;
		bool onLadder = false;
		if (isMob)
		{
			_maxVelocity = mobVelocity;
		}
		else
		{
			_maxVelocity = 8f;
		}
		float curentMaxVelocity = _maxVelocity;
		while (true)
		{
			if (!isIdle && !isMob)
			{
				curTransitionTime -= Time.deltaTime;
				if (curTransitionTime < 0f && !TPSCamera.instance.streif)
				{
					Idle(true);
					isIdle = true;
				}
			}
			Vector3 prevPos = ((isMob || !(curentBehavior != null) || !(curentBehavior.currentCar != null) || !curentBehavior.inCar) ? ((!inParent) ? base.transform.position : base.transform.localPosition) : curentBehavior.currentCar.transform.position);
			yield return new WaitForEndOfFrame();
			Vector3 curPos = ((isMob || !(curentBehavior != null) || !curentBehavior.inCar || !(curentBehavior.currentCar != null)) ? ((!inParent) ? base.transform.position : base.transform.localPosition) : curentBehavior.currentCar.transform.position);
			if (isMob)
			{
				Vector3 direction = base.transform.InverseTransformDirection(curPos) - base.transform.InverseTransformDirection(prevPos);
				if (isMobMoving)
				{
					Move(currentVelocuty, 0f);
				}
				else
				{
					Move(0f, 0f);
				}
				if (direction.magnitude > 0f && isMobMoving)
				{
					SetBoolAnim("IsMoving", true);
				}
				else
				{
					SetBoolAnim("IsMoving", false);
				}
			}
			else
			{
				if (!(mesh != null) || !mesh.isVisible)
				{
					continue;
				}
				onLadder = !isMob && !shopPlayer && _animator.GetBool("OnLadder");
				curentMaxVelocity = ((!onLadder) ? _maxVelocity : (_maxVelocity / 10f));
				Vector3 direction;
				if (!isMob && curentBehavior != null && curentBehavior.inCar && (bool)curentBehavior.currentCar)
				{
					float z = (curentBehavior.currentCar.transform.InverseTransformDirection(curPos) - curentBehavior.currentCar.transform.InverseTransformDirection(prevPos)).z;
					direction = new Vector3(0f, 0f, z);
				}
				else
				{
					direction = base.transform.InverseTransformDirection(curPos) - base.transform.InverseTransformDirection(prevPos);
				}
				if (!onLadder)
				{
					currentVelocuty = Mathf.Lerp(prevVel, (direction / Time.unscaledDeltaTime).magnitude / curentMaxVelocity, 4f * Time.unscaledDeltaTime);
				}
				else
				{
					currentVelocuty = (direction / Time.unscaledDeltaTime).magnitude / curentMaxVelocity;
				}
				currentVelocuty = (float)(int)(currentVelocuty * 1000f) / 1000f;
				if (currentVelocuty > 0.05f)
				{
					RefreshTransitionState();
				}
				if (isGrounded && !inWater)
				{
					if (!onLadder && (isMob || !curentBehavior.inCar) && (prevVel < 0.05f || !_animator.GetBool("IsMoving")) && currentVelocuty > 0.05f)
					{
						if (isMob || !curentBehavior.isImmortal)
						{
							SetBoolAnim("IsMoving", true);
							isMoving = true;
						}
						SwitchUpperLayer(true);
					}
					else if (currentVelocuty < 0.05f && (prevVel > 0.05f || isMoving))
					{
						SetBoolAnim("IsMoving", false);
						isMoving = false;
					}
				}
				else if (_animator.GetBool("IsMoving"))
				{
					SetBoolAnim("IsMoving", false);
					Move(0f, 0f);
					isMoving = false;
				}
				if (!isMob && curentBehavior != null && curentBehavior.inCar)
				{
					if (currentVelocuty - prevVel > 0.01f)
					{
						currentVelocuty = prevVel + 0.01f;
					}
					else if (prevVel - currentVelocuty < -0.01f)
					{
						currentVelocuty = prevVel - 0.01f;
					}
					currentVelocuty = (prevVel + currentVelocuty) * 4f;
					prevVel = currentVelocuty / 8f;
				}
				else
				{
					prevVel = currentVelocuty;
				}
				if (onLadder)
				{
					Move(direction.normalized.y + Mathf.Abs(direction.normalized.x) * currentVelocuty, 0f);
					continue;
				}
				Vector3 oldDirection = direction;
				Move(direction.normalized.z * currentVelocuty, direction.normalized.x * currentVelocuty);
			}
		}
	}

	public void RefreshTransitionState()
	{
		if (isIdle)
		{
			_animator.SetBool("IsIdle", false);
			isIdle = false;
		}
		curTransitionTime = 5f;
	}

	public void CalculateAnimationSpeed(float reloadTime, float timeBetweenShots)
	{
		float num = timeBetweenShots;
		float num2 = reloadTime;
		if (_animator.runtimeAnimatorController != null)
		{
			AnimationClip[] animationClips = _animator.runtimeAnimatorController.animationClips;
			AnimationClip[] array = animationClips;
			foreach (AnimationClip animationClip in array)
			{
				if (animationClip.name == "shoot")
				{
					num = animationClip.length;
				}
				if (animationClip.name == "reload")
				{
					num2 = animationClip.length;
				}
			}
		}
		if (reloadTime < 0.1f)
		{
			reloadTime = 0.1f;
		}
		if (timeBetweenShots < 0.1f)
		{
			timeBetweenShots = 0.1f;
		}
		SetFloatAnim("ReloadSPEED", num2 / reloadTime);
		SetFloatAnim("ShootSPEED", num / timeBetweenShots);
	}

	private IEnumerator OnUpperBody()
	{
		yield return new WaitForSeconds(1f);
		SwitchUpperLayer(true);
	}

	private void Move(float straightSpeed, float sideSpeed)
	{
		SetFloatAnim("SpeedStraight", straightSpeed);
		SetFloatAnim("SpeedSide", sideSpeed);
	}
}
